#ifndef _skel_H_
#define _skel_H_

#include <algorithm>

#include <vector>

#include "filter.h"
#include "Image.H"
#include "IO.H"
#include "Util.H"

using namespace std;
using namespace pip;

class skel
{
public:
  // Constructor, sets k to 1 as default
  skel(const int& iterations = 3);
  void thin( Image<unsigned char> & im);
private:
  Image<unsigned char> hitmiss(Image<unsigned char> &input,  const BorderInfo &bi =  pip::border_mirror);
  int iterations_; 
  static const int kernels[8][9]; 
  vector<Image<unsigned char>> masks;
  Image<unsigned char> tmp;
};

const int skel::kernels[8][9] = {   { 1, 1, 1 , 0, 2, 0 ,  2, 2, 2  },
									{  0, 1, 1, 2, 2, 1 ,  0, 2, 0 },
									{  2, 0, 1 , 2, 2, 1 , 2, 0, 1  },
									{  0, 2, 0 , 2, 2, 1, 0, 1, 1  },
									{  2, 2, 2 , 0, 2, 0, 1, 1, 1  },
									{  0, 2, 0 , 1, 2, 2, 1, 1, 0  },
									{  1, 0, 2 , 1, 2, 2, 1, 0, 2  },
									{  1, 1, 0 , 1, 2, 2 , 0, 2, 0  } };

skel::skel(const int& iterations){
	iterations_=iterations;
	for(int fill =0; fill < 8 ; ++fill){
		Image<unsigned char> mask(Dimension(3,3));
		for(int pos=0; pos < 9;++pos){
			mask(pos/3,pos%3)=kernels[fill][pos];
			masks.push_back(mask);
		}
	}
}

void skel::thin(Image<unsigned char> & im){
	Image<unsigned char> hit;
	const Image<unsigned char> copy(im);
	for (int i = 0; i < iterations_; ++i){
	  hit=hitmiss(im);
	  for (int y = 0; y < copy.dim(1); ++y) {
		for (int x = 0; x < copy.dim(0); ++x) {
			if(    im(x,y) > 0 
				&& hit(x,y) == 0 ){
				im(x,y)=255;
			}else{
				im(x,y)=0;
			}
		}
	  }

	}
}


Image<unsigned char> skel::hitmiss(Image<unsigned char> &input, const BorderInfo &bi)
{
  int centre((masks[1].dim(0) - 1) / 2),hit(0),to_hit(7);
  Image<unsigned char> temp(input.bordered(centre, bi));

  //output.resize(input.dimension());
  temp.fill(0);

  // Loop over all pixels
  for (int y = 0; y < input.dim(1); ++y) {
    for (int x = 0; x < input.dim(0); ++x) {
	  for(unsigned int ma=0; ma< masks.size();++ma){
		  hit=0;
		  if(masks[ma](0,0) == 0 || masks[ma](2,0) == 0){
			to_hit = 6;
		  }else{
            to_hit = 7;
		  }
		  for (int dy = -centre; dy <= centre; ++dy) {
			for (int dx = -centre; dx <= centre; ++dx) {
				if( 0 <  masks[ma](centre - dx, centre - dy)){
					if ( 1 == masks[ma](centre - dx, centre - dy)){
						if(0 == input(x + dx, y + dy)){
							hit++;
						}else{
							dy=100;dx=100;
							break;
						}
					}else{
						if( 0 < input(x + dx, y + dy)){
							hit++;
						}else{
							dy=100;dx=100;
							break;
						}
					}
				}
				if(hit >= to_hit){
					temp(x,y)=255;
					ma=100;dy=100;dx=100;
					break;
				}
			}
		  }
	  }
	}
  }
  return temp;
}




#endif